在开发大型项目,编写复杂业务逻辑时,我们就期望代码在运行到某个位置时能够暂停,这样方便我们定位问题和实时常看一些变量的值。
此刻我们就需要进行代码调试,以便于快速定位问题,提高开发效率。
接下来介绍几种 Node.js 的调试方式和调试技巧:
我们先来一段用于调试的代码 debug.js
,方便后续的展开。
ts
// 声明一个数组并初始化
const myArray = [1, 2, 3, 4, 5]
// 声明一个对象并初始化
const myObject = {
name: 'Alice',
age: 30,
city: 'New York'
}
// 输出原始数组和对象
console.log('The original array is:', myArray)
console.log('The original object is:', myObject)
// 向数组中添加一个元素
myArray.push(6)
// 更新对象中的一个属性
myObject.age = 31
// 输出修改后的数组和对象
console.log('The modified array is:', myArray)
console.log('The modified object is:', myObject)
先为代码添加 2 个断点 (点击数字旁边的空白区域就能完成添加),如下图所示。
通过 VS Code 触发调试的方式有很多,下面介绍几个常用的。
按 F5
或者在右侧点击 运行和调试
,
在弹出框中选择 Node.js
。
在新建终端位置有个 JavaScript调试终端选项
,或者 运行和调试
面板处,
通过这个调试终端执行指令都会唤起 debug 模式。
在日常开发中,运行项目一般都是通过执行 npm 脚本,
比如开发启动项目 npm run dev
,构建项目 npm run build
等等。
package.json
内容如下。
json
{
"scripts": {
"dev": "node debug-chrome.js",
"build": "node debug-chrome.js"
}
}
可以通过上面的 js调试终端
运行进入调试,
也可以在编辑器中触发。
在调试程序启动后,咱们可以看见有个黄色的箭头停在了第一个断点处,
在左侧可以看到 变量
,调用堆栈
,监视
,断点
等小窗口,
调试控制台里会展示 console
打印的信息,顶部还有一个 debug
控制条,
下面我们逐个介绍每个窗口的作用。
展示此时此刻所有变量的信息,包含局部和本地,可以手动展开详细查看每个变量的数据和结构。
同时还可以手动修改,直接双击要修改的变量,直接编辑即可,按 Enter(回车)
保存。
同时在编辑代码的区域,也可把鼠标悬浮上去,查看此时变量的信息。
这部分可以编写自定义的表达式
比如下面的例子,添加了查看数组 1,2
两项目的值与和。
当相关值变动时,表达试的值也会变动。
一共 6 个按钮,作用介绍如下。
① 继续执行
点击后会继续执行代码,直到发现下一个断点。
② 单步跳过
直接执行下一条语句,并跳过当前函数内部的所有语句。
如上图所示,不会执行 console.log 内部的逻辑,直接调到了下一个 console 语句,表现上像一行行的执行了,
可以和下面的单步调试对比一下。
③ 单步调试
执行下一条语句并进入当前函数内部继续调试,
从左下角的调用堆栈可以看出来,是进入了 console.log 函数内部执行。
不习惯使用 VS Code 里操作调试的话也可以使用浏览器进行调试。
在使用命令行执行脚本时添加一个参数 --inspect-brk
,
表示以调试模式启动并且在首行断住。
sh
node --inspect-brk ./debug.js
可以看到终端里打印了一个 WebSocket
地址。
此时使用 Chrome/Edge
访问 chrome://inspect
或者 edge://inspect
就能看到咱们 debug 的目标程序,
点击 inspect 就能看见和 VS Code 里类似的调试面板了,
同样的也是在左侧行号处添加断点,右侧包含与 VS Code
一样作用的 监视器
、断点
、变量
,调用堆栈
等面板。
当然断点也可以直接写在代码里,关键字为 debugger
。
咱们就用下面的代码来进行测试。
js
// 声明一个名为 print 的函数,用于打印传入的值
function print(value) {
debugger
console.log('print', value) // 输出传入的值
}
// 声明一个数组并初始化
const myArray = [1, 2, 3, 4, 5]
// 声明一个对象并初始化
const myObject = {
name: 'Alice',
age: 30,
city: 'New York'
}
debugger
// 调用 print 函数,传入 myArray 作为参数,打印 myArray
print(myArray)
// 调用 print 函数,传入 myObject 作为参数,打印 myObject
print(myObject)
下面是实操演示。
没有 IDE,没有 Chrome 能调试吗?当然能!!!
Node 内置了命令行中调试的指令,下面慢慢道来。
inspect
是 Node.js 提供的一个命令行工具,具体用法如下:
sh
node inspect debug-inspect.js
这里仍然使用上面的代码进行调试演示,debugger
同样生效。
js
// 声明一个名为 print 的函数,用于打印传入的值
function print(value) {
debugger
console.log('print', value) // 输出传入的值
}
// 声明一个数组并初始化
const myArray = [1, 2, 3, 4, 5]
// 声明一个对象并初始化
const myObject = {
name: 'Alice',
age: 30,
city: 'New York'
}
debugger
// 调用 print 函数,传入 myArray 作为参数,打印 myArray
print(myArray)
// 调用 print 函数,传入 myObject 作为参数,打印 myObject
print(myObject)
下面是一些常用的指令
| 指令 | 功能 |
| -------------------- | --------------------------------------------------------------------------------------------------- |
| sb
、setBreakpoint
| 在代码中的任何位置设置断点。可以使用 sb(10)
在第 10 行设置断点; sb('filename.js', 10)
在 filename.js
文件的第 10 行设置断点 |
| c
、cont
| 继续执行程序,直到碰到下一个断点或者程序结束 |
| n
、next
| 跳过当前行,执行下一行,并停在下一行 |
| s
、step
| 进入当前行调用的函数,如果当前行没有函数调用,则执行下一行,并停在下一行 |
| o
、out
| 跳出当前函数,到调用当前函数的函数处,并停在该函数的下一行 |
| repl
| 进入 REPL 模式。在该模式下,你可以查看变量的值,运行任何表达式,甚至修改变量的值,而不需要停止程序运行 |
| watch
| 观察变量的值的改变。例如, watch('myArray')
将观察 myArray
变量的值的改变,每当它的值改变时,调试器都会记录下来。 |
当然还提供了许多其他的指令,例如 list(打印当前执行到的代码)
、backtrace(调用堆栈信息)
等等。你可以在调试过程中随时输入 help
来查看所有可用的指令。
下面演示一下常用指令的用法。
除了使用 debugger
设置断点也可以在运行时使用 sb
设置,操作如下。
使用 c
,n
,s
,o
均可执行,具体效果如上面阐述那样,和 VS Code 里的调试工具调按钮作用一一对应。
使用 list
方法,list()
显示当前执行到的位置,list(12)
显示第 12 行的代码。
使用 r
。
watch
设置监视器,watchers
查看所有监视器的情况。
使用 bt
。
本节主要介绍了 3 种 Node.js 的调试方法,前两种图形化调试方法,是最常用的,命令行调试方法了解即可 (在某些没有 UI 的场合能够用上),
期望大家能够掌握这些常用的调试技巧和方法,提高开发效率。